Githook实践以代码规范检测插件golangci 您所在的位置:网站首页 golangci-lint 插件 Githook实践以代码规范检测插件golangci

Githook实践以代码规范检测插件golangci

2024-07-14 23:03| 来源: 网络整理| 查看: 265

「这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战」

引子

"kovogo哥, 我怎么提交不了代码了"

没想到工作两年就已经进入哥字辈了, 往旁边一看旁边新来的小伙子正常对着屏幕发愁, 一看控制台的报错,哦原来是golangci-lint打回了提交, 原因是某一行的代码太长了超过了限制。

那么在提交代码对代码规范进行检查是怎么做到的? 这就需要我们来回顾一下githook的知识了。

githook

什么是githook?

一般来说只要是上了规模的软件/中间件/开源框架或多或少的会提供一些hook, 供开发人员使用。而这些hook的作用就是在这些框架/软件中引入开发人员编写代码, 从而改变软件的表现形式或行为逻辑。

而githook就是git是向开发者提供的在git执行重要的操作引入开发者的代码的功能,比如上文提到在commit时引入代码检查的功能就是通过githook实现的。

每个git仓库在初始化的时候, 都会在.git目录下创建一个hooks目录,用来存放开发人员自定义的hook脚本(shell脚本), 脚本文件名即hook名。

windows 环境安装git时会自带git bash, 因此无需要担心脚本的兼容性

当hook脚本返回0时表示放行对应的操作, 返回非0值表示拒绝此操作。

每个程序在退出的时候都会有返回值, 该返回值通常用来表示程序是否执行成功.

在Linux shell中我们可以通过, $?来获取上一个程序的返回值.

image.png

如上图所示, 我们尝试访问一个不存在的路径, ls命令的返回值是2.

我们可以在.git/hooks中看到如下文件:

image.png

上图中.sample文件都是git官方提供的参考, 去掉.sample后缀该钩子就会起效, 记住: 文件名即钩子名

如果需要在提交代码时对代码进行检测,我们就需要为pre-commit钩子编写代码规范检测脚本。

更多详细信息可参见官方文档

golintci-lint

由于golint已经被谷歌抛弃不再维护了, 我们使用了golangci-lint对代码规范进行检查。

安装

golangci-lint官网给出的安装方式有两种:

二进制安装, 直接下载对应平台的可执行文件 如果版本小于1.16使用go get下载源文件并编译安装, 大于1.16则使用go install # Go 1.16+ go install github.com/golangci/golangci-lint/cmd/[email protected] # Go version < 1.16 go get -u github.com/golangci/golangci-lint/cmd/[email protected] 复制代码

以windows平台为例, 我的golang版本是1.16.10

image.png

因此我们使用go install的方式进行安装

image.png

使用

使用run命令即可对目标目录的代码进行检测

golangci-lint run [目录] 复制代码

使用-h可以查看run命令的更多帮助信息

golangci-lint run -h 复制代码

image.png

值得注意的选项有:

--issues-exit-code 代码检测失败返回的错误码, 默认是1 -c, --config PATH 用于定制代码检测项目的配置文件(yaml格式) --skip-files 要跳过的文件 --skip-dirs 要跳过的目录 --enable 要启用的代码检测项目 定制代码检测

上文提到, 我们可以通过--config来定制代码检测项目的配置, 其格式如下:

linters-settings: cyclop: # 代码检测项目名通常会对应到某个插件 # 最大的复杂度 max-complexity: 10 # 每个包允许的最大复杂度 package-average: 0.0 # 是否跳过测试文件 skip-tests: false 复制代码

更多信息参考官方文档

githook + golangci-lint

以windows平台为例, 我们新建一个项目

image.png

然后新建一个代码文件, 随便写点乱七八糟的代码:

func main() { for i := 0; i < 1024; i++ { for j := 0; j < 1024; j++ { for n := 0; n < 1024; n++ { fmt.Printf("%d-%d-%s", i, j, n) } } } } 复制代码

golangci-lint检测到了Printf传了错误的参数

image.png

我们再往项目中里面加点有"坏味道"的代码, 如下所示:(示例来自cyclop项目的测试文件)

func T() { i := 1 if i > 2 { if i > 2 { } if i > 2 { } if i > 2 { } if i > 2 { } } else { if i > 2 { } if i > 2 { } if i > 2 { } if i > 2 { } } if i > 2 { } } 复制代码

再次进行代码检测, 注意此时需要启用圈复杂度检测插件cyclop

image.png

如果我们想要让代码通过检测,就需要使用到上文提到的使用配置文件自定义代码检测项目了。

在项目中创建lint.yaml, 并编写配置项如下

linters-settings: cyclop: # 最大的复杂度 max-complexity: 15 # 每个包允许的最大复杂度 package-average: 0.0 # 是否跳过测试文件 skip-tests: false 复制代码

再次运行并指定配置文件, 此时已不再提示圈复杂度过高

image.png

pre-commit hook

利用上文的知识,我们的pre-commit hook 脚本的逻辑如下所示:

检测是否安装golangci-lint, 如果没有则进行安装 运行golangci-lint对代码进行检测,如果检测失败返回1成功则返回0 #!/bin/sh echo "Start lint code" if !(golangci-lint.exe --version); then go install github.com/golangci/golangci-lint/cmd/[email protected] fi # 目录名后跟上...表示对该目录进行递归查找 if !(golangci-lint.exe run --enable cyclop --config ./lint.yaml ./...); then echo "Lint fail!" exit 1 fi echo "Lint success" exit 0 复制代码

尝试对代码提交,运行效果如下图所示 image.png



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有